<template>
  <div class="GenerateFieldsForm">
    <!-- 按钮 -->
    <el-row>
      <el-col>
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="small"
          @click="addField"
        >
          新增
        </el-button>
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="small"
          @click="deleteField"
          :disabled="selectedFieldsList.length === 0"
        >
          删除
        </el-button>
      </el-col>
    </el-row>
    <!-- 表单 -->
    <el-form
      :model="fieldFroms"
      :rules="rules"
      label-width="0"
      size="small"
      @submit.native.prevent="
        () => {
          return;
        }
      "
    >
      <el-table
        :data="fieldFroms.tableFileds"
        tooltip-effect="dark"
        style="width: 100%; border: 1px solid #efefef"
        height="100%"
        @cell-click="cellClick"
        @selection-change="selectedFields"
        size="small"
      >
        <!-- 排序列 -->
        <el-table-column width="55" align="center">
          <column-slot slot="header" type="sort"></column-slot>
          <template>
            <span class="iconfont icon-sort ape-table-sort-icon"> </span>
          </template>
        </el-table-column>
        <!-- 选择 -->
        <el-table-column
          type="selection"
          :selectable="isSelectable"
          width="55"
          align="center"
        >
        </el-table-column>
        <!-- 序号 -->
        <el-table-column type="index" label="#" width="55" align="center">
        </el-table-column>
        <!-- 字段名称 -->
        <el-table-column prop="fieldName" width="150" align="center">
          <column-slot slot="header" name="字段名称" required></column-slot>
          <template slot-scope="scope">
            <el-form-item
              :prop="`tableFileds.${scope.$index}.fieldName`"
              :rules="rules.fieldName"
              :show-message="!tableFormShow(scope, 'fieldName')"
            >
              <template #error="{ error }">
                <div class="ruleError">
                  {{ error }}
                </div>
              </template>
              <column-slot
                type="cell"
                name="字段名称"
                :scope="scope"
                :editId.sync="editId"
                field="fieldName"
                :disabled="scope.row.default"
              ></column-slot>
            </el-form-item>
          </template>
        </el-table-column>
        <!-- 字段类型 -->
        <el-table-column prop="fieldType" width="170" align="center">
          <column-slot slot="header" name="字段类型" required></column-slot>
          <template slot-scope="scope">
            <column-slot
              type="cell"
              name="字段类型"
              :scope="scope"
              :editId.sync="editId"
              field="fieldType"
              cell-type="select"
              :select-data="fieldTypeList"
              :disabled="scope.row.default"
            ></column-slot>
          </template>
        </el-table-column>
        <!-- 字段长度 -->
        <el-table-column prop="fieldLength" width="150" align="center">
          <column-slot slot="header" name="字段长度" required></column-slot>
          <template slot-scope="scope">
            <el-form-item
              :prop="`tableFileds.${scope.$index}.fieldLength`"
              :rules="rules.fieldLength"
              :show-message="!tableFormShow(scope, 'fieldLength')"
            >
              <template #error="{ error }">
                <div class="ruleError">
                  {{ error }}
                </div>
              </template>
              <column-slot
                type="cell"
                name="字段长度"
                :scope="scope"
                :editId.sync="editId"
                field="fieldLength"
                inputType="number"
                :disabled="scope.row.default"
              ></column-slot>
            </el-form-item>
          </template>
        </el-table-column>
        <!-- 小数点 -->
        <el-table-column prop="fieldDecimal" width="140" align="center">
          <column-slot slot="header" name="小数点" required></column-slot>
          <template slot-scope="scope">
            <el-form-item
              :prop="`tableFileds.${scope.$index}.fieldDecimal`"
              :rules="rules.fieldDecimal"
              :show-message="!tableFormShow(scope, 'fieldDecimal')"
            >
              <template #error="{ error }">
                <div class="ruleError">
                  {{ error }}
                </div>
              </template>
              <column-slot
                type="cell"
                name="小数点"
                :scope="scope"
                :editId.sync="editId"
                field="fieldDecimal"
                inputType="number"
                :disabled="scope.row.default"
              ></column-slot>
            </el-form-item>
          </template>
        </el-table-column>
        <!-- 字段备注 -->
        <el-table-column
          prop="fieldNotes"
          show-overflow-tooltip
          align="center"
          width="180"
        >
          <column-slot slot="header" name="字段备注" required></column-slot>
          <template slot-scope="scope">
            <el-form-item
              :prop="`tableFileds.${scope.$index}.fieldNotes`"
              :rules="rules.fieldNotes"
              :show-message="!tableFormShow(scope, 'fieldNotes')"
            >
              <template #error="{ error }">
                <div class="ruleError">
                  {{ error }}
                </div>
              </template>
              <column-slot
                type="cell"
                name="字段备注"
                :scope="scope"
                :editId.sync="editId"
                field="fieldNotes"
                :disabled="scope.row.default"
              ></column-slot>
            </el-form-item>
          </template>
        </el-table-column>
        <!-- 默认值 -->
        <el-table-column
          prop="fieldDefault"
          show-overflow-tooltip
          align="center"
        >
          <column-slot slot="header" name="默认值"></column-slot>
          <template slot-scope="scope">
            <column-slot
              type="cell"
              name="默认值"
              :scope="scope"
              :editId.sync="editId"
              field="fieldDefault"
              :disabled="scope.row.default"
            ></column-slot>
          </template>
        </el-table-column>
        <!-- 非空 -->
        <el-table-column prop="fieldNotNull" width="80" align="center">
          <column-slot slot="header" name="非空"></column-slot>
          <template slot-scope="scope">
            <el-checkbox
              v-model="scope.row.fieldNotNull"
              :disabled="scope.row.default"
              :true-label="1"
              :false-label="0"
            ></el-checkbox>
          </template>
        </el-table-column>
        <!-- 主键 -->
        <el-table-column prop="fieldPrimarykey" width="80" align="center">
          <column-slot slot="header" name="主键"></column-slot>
          <template slot-scope="scope">
            <el-checkbox
              v-model="scope.row.fieldPrimarykey"
              :disabled="scope.row.default"
              :true-label="1"
              :false-label="0"
            ></el-checkbox>
          </template>
        </el-table-column>
        <!-- 字符集 -->
        <el-table-column prop="fieldCharacter" width="160" align="center">
          <column-slot slot="header" name="字符集"></column-slot>
          <template slot-scope="scope">
            <column-slot
              type="cell"
              name="字符集"
              :scope="scope"
              :editId.sync="editId"
              field="fieldCharacter"
              cell-type="select"
              :select-data="Array.from(filedCharMap.keys())"
              clear="fieldCollation"
              :disabled="scope.row.default"
            ></column-slot>
          </template>
        </el-table-column>
        <!-- 排序规则 -->
        <el-table-column prop="fieldCollation" width="180" align="center">
          <column-slot slot="header" name="排序规则"></column-slot>
          <template slot-scope="scope">
            <column-slot
              type="cell"
              name="排序规则"
              :scope="scope"
              :editId.sync="editId"
              field="fieldCollation"
              cell-type="select"
              :select-data="filedCharMap.get(scope.row.fieldCharacter)"
              :disabled="scope.row.default"
            ></column-slot>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
  </div>
</template>

<script>
import { fieldType, fieldChar } from "@/utils/dbInfos";
import columnSlot from "./columnSlot.vue";
export default {
  name: "GenerateFieldsForm",

  components: {
    columnSlot,
  },

  props: {
    form: {
      type: Object,
      default: () => {
        return {
          tableFileds: [],
        };
      },
    },
  },

  data() {
    return {
      // 表单数据表字段选中数组
      selectedFieldsList: [],
      // 当前可编辑字段标识
      editId: null,
      // 数据表字段类型
      fieldTypeList: fieldType,
      // 数据表字符集 map
      filedCharMap: new Map(Object.entries(fieldChar)),
      // 表单校验
      rules: {
        fieldName: [
          {
            validator: this.rulesFunction,
            trigger: "change",
            required: true,
          },
        ],
        fieldLength: [
          {
            validator: this.rulesFunction,
            trigger: "change",
            required: true,
          },
        ],
        fieldDecimal: [
          {
            validator: this.rulesFunction,
            trigger: "change",
            required: true,
          },
        ],
        fieldNotes: [
          {
            validator: this.rulesFunction,
            trigger: "change",
            required: true,
          },
        ],
      },
    };
  },

  computed: {
    fieldFroms: {
      get() {
        return this.form;
      },
      set(value) {
        this.$emit("update:form", value);
      },
    },
  },

  mounted() {},

  methods: {
    // 校验规则
    rulesFunction(rule, value, callback) {
      let filed = rule.field.split(".");
      if (!filed[filed.length - 2] || filed[filed.length - 2] != 0) {
        switch (filed[filed.length - 1]) {
          case "fieldName":
            this.fieldNameRule(rule, value, callback);
            break;

          case "fieldLength":
            if (value === null) {
              callback(new Error("字段长度不能为空"));
            } else {
              callback();
            }
            break;

          case "fieldDecimal":
            if (value === null) {
              callback(new Error("小数点不能为空"));
            } else {
              callback();
            }
            break;

          case "fieldNotes":
            if (value === null) {
              callback(new Error("字段备注不能为空"));
            } else {
              callback();
            }
            break;

          default:
            break;
        }
      } else {
        callback();
      }
    },
    // 字段名校验
    fieldNameRule(rule, value, callback) {
      // 匹配是否包含中文
      const regex = /[\u4e00-\u9fa5]/;
      // 匹配开头是否有数字
      const regex1 = /^\d/;
      // 匹配除字母、数字和_和$之外的特殊字符
      const regex2 = /[^a-zA-Z0-9_$]/;
      // 是否重复
      const repeatCount = this.fieldFroms.tableFileds.filter(
        (item) => item.fieldName === value
      );
      // 校验字段
      if (value === null || value.trim() === "") {
        callback(new Error("字段名不能为空"));
      } else if (value.includes(" ")) {
        callback(new Error("字段名不能包含空格"));
      } else if (regex.test(value)) {
        callback(new Error("不允许输入中文"));
      } else if (regex1.test(value)) {
        callback(new Error("不允许数字开头"));
      } else if (regex2.test(value)) {
        callback(new Error("字段名只允许字母、数字、_、$"));
      } else if (repeatCount.length >= 2) {
        callback(new Error("字段名已经存在了"));
      } else {
        callback();
      }
    },
    // 添加字段
    addField() {
      this.fieldFroms.tableFileds.push({
        fieldName: "",
        fieldType: "varchar",
        fieldLength: 255,
        fieldDecimal: 0,
        fieldNotes: null,
        fieldDefault: null,
        fieldNotNull: false,
        fieldPrimarykey: false,
        fieldCharacter: "utf8",
        fieldCollation: "utf8_general_ci",
        form: true,
        table: true,
        sort: false,
        readonly: false,
        required: false,
        search: false,
        searchType: "=",
        controlType: "dict1",
        controlDefault: "",
        dictType: "",
        isEdit: 1,
      });
      this.editId = `fieldName${this.fieldFroms.tableFileds.length - 1}`;
    },
    // 删除字段
    deleteField() {
      let list = this.selectedFieldsList;
      list.forEach((filed) => {
        let index = this.fieldFroms.tableFileds.findIndex(
          (item) => item === filed
        );
        this.fieldFroms.tableFileds.splice(index, 1);
      });
    },
    // 选择字段
    selectedFields(e) {
      this.selectedFieldsList = e;
    },
    // 单元格单击事件
    cellClick(row, column) {
      const index = this.fieldFroms.tableFileds.findIndex(
        (item) => item === row
      );
      const editId = (column.property || "null") + index;
      if (this.editId !== editId) {
        this.editId = editId;
      }
    },
    // 是否可选择行
    isSelectable(row) {
      if (row.default) {
        return false;
      } else {
        return true;
      }
    },
    // 是否编辑字段
    tableFormShow(scope, filed) {
      let str = filed + scope.$index;
      if (scope.row.default) {
        return true;
      } else if (str === this.editId) {
        return false;
      } else {
        return true;
      }
    },
  },
};
</script>

<style lang="scss">
.GenerateFieldsForm {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;

  .el-form {
    margin-top: 10px;
    width: 100%;
    height: 0;
    flex: 1;

    // 表格单元格
    .cell {
      overflow: inherit;

      .el-form-item {
        position: relative;
        margin: 0;
      }

      .ruleError {
        padding: 2px;
        position: absolute;
        top: -45px;
        left: 10px;
        width: calc(100% - 20px);
        height: 40px;
        color: #ffffff;
        font-size: 12px;
        line-height: 18px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 5px;
        background: #f56c6c;
        box-sizing: border-box;
      }

      .el-input__inner[type="number"]::-webkit-inner-spin-button,
      .el-input__inner[type="number"]::-webkit-outer-spin-button {
        -webkit-appearance: none;
        margin: 0;
      }
    }
  }
}
</style>
